package com.samsung.booksmanagement;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import com.example.goup17booksmanagement.R;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends Activity {

	private Context mContext;
	private EditText edtSearchBar;
	private ImageButton btnAdd;
	private ListView lsvBookList;
	private ArrayList<Book> bookList;
	private ArrayAdapter<Book> bookAdapter;
	private ArrayList<Book> searchList;
	private ArrayAdapter<Book> searchAdapter;
	private boolean isSearching;
	private int alarmId = -1;
	private String alarmBookName = "";
	private int CREATE_NEW_BOOK = 1;
	private int EDIT_BOOK = 2;
	private int VIEW_MODE = 3;
	private Book tempBook; // Using in contextmenu process

	private int hour = 0;
	private int minute = 0;
	static final int TIME_DIALOG_ID = 999;
	Calendar alarmCalendar;

	// database service
	private DatabaseSevice mDatabaseService;

	private Handler mhandlerService = new Handler();

	ServiceConnection mServiceConnection = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			mDatabaseService = null;
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			mDatabaseService = ((DatabaseSevice.DatabaseServiceBinder) service)
					.getDatabaseService();
			mhandlerService.post(new GetData());
		}
	};

	private class GetData implements Runnable {
		@Override
		public void run() {
			bookList.clear();
			bookList.addAll(mDatabaseService.listAllBook());
			bookAdapter.notifyDataSetChanged();
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		bindService(new Intent(this, DatabaseSevice.class), mServiceConnection,
				Context.BIND_AUTO_CREATE);

		mContext = this;
		isSearching = false;
		alarmCalendar = Calendar.getInstance();

		// Bind UI
		edtSearchBar = (EditText) findViewById(R.id.editSearch);
		btnAdd = (ImageButton) findViewById(R.id.btnAdd);
		lsvBookList = (ListView) findViewById(R.id.lsvBookList);

		// Setting Up search List
		searchList = new ArrayList<Book>();
		searchAdapter = new BookAdapter(mContext, searchList);

		// Setting up Adater for list view
		bookList = new ArrayList<Book>();
		bookAdapter = new BookAdapter(mContext, bookList);
		lsvBookList.setAdapter(bookAdapter);

		// Even Matching
		// EditText Search
		edtSearchBar.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				// TODO Auto-generated method stub
				performSearch();

			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub
			}

			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub
			}
		});

		// On List View Item Click
		lsvBookList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				Intent senderIntent = new Intent(mContext, ViewBookDetail.class);
				Book temp;
				if (isSearching) {
					temp = searchList.get(arg2);
				} else {
					temp = bookList.get(arg2);
				}
				// Toast.makeText(mContext, temp.getName(),
				// Toast.LENGTH_LONG).show();
				senderIntent.putExtra("mode", "view_mode");
				senderIntent.putExtra("id", "" + temp.getId());
				senderIntent.putExtra("index", "" + arg2);
				senderIntent.putExtra("name", temp.getName());
				senderIntent.putExtra("author", temp.getAuthor());
				senderIntent.putExtra("publisher", temp.getPublisher());
				senderIntent.putExtra("publishdate", temp.getPublishDate());

				startActivityForResult(senderIntent, VIEW_MODE);
			}
		});

		// Setting Up event for button Add New
		btnAdd.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				searchList.clear();
				Intent senderIntent = new Intent(mContext, AddAndEdit.class);
				senderIntent.putExtra("mode", "create_new_mode");
				startActivityForResult(senderIntent, CREATE_NEW_BOOK);
			}
		});
		registerForContextMenu(lsvBookList);
	}

	// Handler and inner class for notify lv adapter data set change
	private Handler mhandler = new Handler();

	class SetChangeSearch implements Runnable {
		@Override
		public void run() {
			searchAdapter.notifyDataSetChanged();
		}
	}

	private void performSearch() {
		lsvBookList.setAdapter(searchAdapter);
		searchList.clear();
		searchAdapter.notifyDataSetChanged();
		isSearching = true;

		Thread searchThread = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				String keyWord = edtSearchBar.getText().toString();
				searchList.clear();
				for (Book a : bookList) {
					if (a.getName().contains(keyWord)) {
						searchList.add(a);
						mhandler.post(new SetChangeSearch());
					}
				}
			}
		});
		searchThread.start();

		return;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK) {
			if (requestCode == CREATE_NEW_BOOK) {
				if (data == null) {
					Toast.makeText(mContext, "NULL DATA", Toast.LENGTH_SHORT)
							.show();
				} else {
					Book temp = new Book();
					String name = data.getStringExtra("name");
					if (name.length() > 0)
						temp.setName(name);

					String author = data.getStringExtra("author");
					if (author.length() > 0)
						temp.setAuthor(author);

					String publisher = data.getStringExtra("publisher");
					if (publisher.length() > 0)
						temp.setPublisher(publisher);

					String publishDate = data.getStringExtra("publishdate");
					if (publishDate.length() > 0)
						temp.setPublishDate(publishDate);

					mDatabaseService.addBook(temp);
					bookList.clear();
					bookList.addAll(mDatabaseService.listAllBook());
					lsvBookList.setAdapter(bookAdapter);
					bookAdapter.notifyDataSetChanged();

				}
			}

			if (requestCode == EDIT_BOOK) {
				if (data == null) {
					Toast.makeText(mContext, "NULL DATA", Toast.LENGTH_SHORT)
							.show();
				} else {
					Book temp = new Book();
					String name = data.getStringExtra("name");
					if (name.length() > 0)
						temp.setName(name);

					String author = data.getStringExtra("author");
					if (author.length() > 0)
						temp.setAuthor(author);

					String publisher = data.getStringExtra("publisher");
					if (publisher.length() > 0)
						temp.setPublisher(publisher);

					String publishDate = data.getStringExtra("publishdate");
					if (publishDate.length() > 0)
						temp.setPublishDate(publishDate);

					String indexString = data.getStringExtra("index");
					int index = Integer.parseInt(indexString);

					String idString = data.getStringExtra("id");
					int id = Integer.parseInt(idString);

					bookList.set(index, temp);
					lsvBookList.setAdapter(bookAdapter);
					mDatabaseService.updateBook(id, temp);
					bookAdapter.notifyDataSetChanged();
				}
			}
		} else if (resultCode == RESULT_CANCELED) {
			if (requestCode == VIEW_MODE) {
				if (data != null) {
					Book temp = new Book();
					String name = data.getStringExtra("name");
					if (name.equals("delete")) {
						String indexString = data.getStringExtra("index");
						int index = Integer.parseInt(indexString);
						bookList.remove(index);
						bookAdapter.notifyDataSetChanged();

						String idString = data.getStringExtra("id");
						int id = Integer.parseInt(idString);
						mDatabaseService.deleteBook(id);
					} else {
						if (name.length() > 0)
							temp.setName(name);

						String author = data.getStringExtra("author");
						if (author.length() > 0)
							temp.setAuthor(author);

						String publisher = data.getStringExtra("publisher");
						if (publisher.length() > 0)
							temp.setPublisher(publisher);

						String publishDate = data.getStringExtra("publishdate");
						if (publishDate.length() > 0)
							temp.setPublishDate(publishDate);

						String indexString = data.getStringExtra("index");
						int index = Integer.parseInt(indexString);

						String idString = data.getStringExtra("id");
						int id = Integer.parseInt(idString);
						mDatabaseService.updateBook(id, temp);

						bookList.set(index, temp);
						lsvBookList.setAdapter(bookAdapter);
						bookAdapter.notifyDataSetChanged();
					}
				}
			}
		}

	}

	// Button Back handler
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			if (isSearching == true) {
				if (bookList.size() == searchList.size())
					finish();
				lsvBookList.setAdapter(bookAdapter);
				searchAdapter.notifyDataSetChanged();
				isSearching = false;
				edtSearchBar.setText("");
				return false;
			} else
				finish();
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		// super.onCreateContextMenu(menu, v, menuInfo);
		getMenuInflater().inflate(R.menu.context_menu, menu);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		// TODO Auto-generated method stub

		AdapterContextMenuInfo adapInfo = (AdapterContextMenuInfo) item
				.getMenuInfo();
		int itemIndex = (int) adapInfo.id;
		tempBook = new Book();
		if (isSearching) {
			tempBook = searchAdapter.getItem(itemIndex);
			itemIndex = bookList.indexOf(tempBook);
		} else {
			tempBook = bookAdapter.getItem(itemIndex);
		}

		switch (item.getItemId()) {
		case R.id.mnEdit:
			Intent senderIntent = new Intent(mContext, AddAndEdit.class);
			senderIntent.putExtra("mode", "edit_mode");
			senderIntent.putExtra("id", "" + tempBook.getId());
			senderIntent.putExtra("index", "" + itemIndex);
			senderIntent.putExtra("name", tempBook.getName());
			senderIntent.putExtra("author", tempBook.getAuthor());
			senderIntent.putExtra("publisher", tempBook.getPublisher());
			senderIntent.putExtra("publishdate", tempBook.getPublishDate());
			startActivityForResult(senderIntent, EDIT_BOOK);
			break;
		case R.id.mnDelete:
			DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					switch (which) {
					case DialogInterface.BUTTON_POSITIVE:
						// Do your Yes progress
						// perform delete
						bookList.remove(tempBook);
						Toast.makeText(mContext, "" + tempBook.getId(),
								Toast.LENGTH_SHORT).show();
						mDatabaseService.deleteBook(tempBook.getId());
						if (isSearching)
							searchList.remove(tempBook);

						bookAdapter.notifyDataSetChanged();
						break;

					case DialogInterface.BUTTON_NEGATIVE:
						// Do your No progress
						break;
					}
				}
			};
			AlertDialog.Builder ab = new AlertDialog.Builder(this);
			ab.setMessage("Are you sure to delete?")
					.setPositiveButton("Yes", dialogClickListener)
					.setNegativeButton("No", dialogClickListener).show();

			break;
		case R.id.mnSetAlarm:
			// perform set Alarm
			alarmId = tempBook.getId();
			alarmBookName = "" + tempBook.getName();
			showTimeDialog(getCurrentFocus());
			break;

		default:
			break;
		}

		return true;
	}

	@SuppressWarnings("deprecation")
	public void showTimeDialog(View v) {
		showDialog(TIME_DIALOG_ID);
	}

	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case TIME_DIALOG_ID:
			return new TimePickerDialog(this, timeSetListener, hour, minute,
					true);
		}
		return null;
	}

	private TimePickerDialog.OnTimeSetListener timeSetListener = new TimePickerDialog.OnTimeSetListener() {

		@SuppressWarnings("deprecation")
		@Override
		public void onTimeSet(TimePicker view, int hourOfDay, int minuteOfHour) {
			// TODO Auto-generated method stub
			hour = hourOfDay;
			minute = minuteOfHour;

			Date tempDate = new Date();
			tempDate.setHours(hour);
			tempDate.setMinutes(minute);
			tempDate.setSeconds(0);
			alarmCalendar = Calendar.getInstance();
			alarmCalendar.setTime(tempDate);

			SetSchedule tempSetSchedule = new SetSchedule(mContext,
					mDatabaseService);
			tempSetSchedule.setOn(alarmCalendar, alarmId, alarmBookName);
			Toast.makeText(
					mContext,
					"Alarm time seted up: "
							+ alarmCalendar.getTime().getHours() + " "
							+ alarmCalendar.getTime().getMinutes(),
					Toast.LENGTH_SHORT).show();
		}
	};

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		unbindService(mServiceConnection);
		super.onDestroy();
	}

}
